<!--
v-model:value       ===> 数据绑定的表单值
name        ===> 默认是file，可以为file,image等，视接口命名
width       ===> 整体宽度
height      ===> 整体高度
accept      ===> 接收的文件类型
maxSize     ===> 允许的文件最大MB
field       ===> v-model默认绑定的字段是id，可以指定：id,filepath,info
imageTitle  ===> 默认显示文件的预览名
imageUrl    ===> 默认显示的文件

Method
finish  ====> 上传完成回调事件
error   ====> 上传失败回调事件
remove  ====> 移除后回调事件
-->
<template>
  <a-upload
      :name="name"
      list-type="picture-card"
      class="s-uploader"
      :before-upload="beforeUpload"
      :customRequest="request"
      :show-upload-list="false"
      @change="handleChange"
      @remove="handleRemove"
      @preview="handlePreview"
      :style="{ width: width, height: height }"
  >
    <div class="template-wrapper">
      <loading-outlined class="loading-icon" v-if="loading"></loading-outlined>
      <template v-if="previewImageUrl">
        <img :src="previewImageUrl" style="width: 100%; height: 100%">
      </template>

      <template v-else>
        <slot v-if="$slots.default"></slot>
        <template v-else>
          <div class="base-flex base-columns base-align-items-center base-justify-content-center" :style="{ width: width, height: height }">
            <plus-outlined v-if="!loading"></plus-outlined>
            <div class="ant-upload-text">点击上传</div>
          </div>
        </template>
      </template>
    </div>
  </a-upload>

  <a-modal :open="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
    <img alt="example" style="width: 100%" :src="previewImage" />
  </a-modal>

</template>

<script setup>
import { computed, getCurrentInstance, onMounted, ref, watch } from 'vue'
import { message, notification } from 'ant-design-vue'
import config from '@/config/upload'
const { proxy } = getCurrentInstance()
const $API = proxy.$API
const $TOOL = proxy.$TOOL
const emit = defineEmits(['finish','error','change','remove','update:value'])
const props = defineProps({
  value: {
    type: [String, Number],
    default: ''
  },
  apiObj: {
    type: Object,
    default: config.apiObj
  },
  name: {
    type: String,
    default: 'file'
  },
  width: {
    type: String,
    default: '152px'
  },
  height: {
    type: String,
    default: '152px'
  },
  accept: {
    type: String,
    default: () => {
      return 'image/gif, image/jpeg, image/png'
    }
  },
  maxSize: {
    type: Number,
    default: config.maxSizeFile
  },
  field: {
    type: String,
    default: 'id'
  },
  imageTitle: {
    type: String,
    default: ''
  },
  imageUrl: {
    type: String,
    default: ''
  }
})

const loading = ref(false)

const previewVisible = ref(false);
const previewImage = ref('');
const previewTitle = ref('');
const previewImageUrl = ref('') // 默认展示图

watch(() => props.imageUrl, (curr, old) => {
  previewImageUrl.value = curr
})

onMounted(() => {
  previewImageUrl.value = props.imageUrl
})

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => resolve(reader.result);
    reader.onerror = error => reject(error);
  });
}

const beforeUpload = (file) => {
  const acceptIncludes = props.accept.replace(/\s/g,"").split(",").includes(file.type)
  if(!acceptIncludes){
    notification.warning({
      message: `上传文件警告`,
      description: '选择的文件为不被允许的类型，仅允许：' + props.accept
    })
    return false
  }

  const maxSize = file.size / 1024 / 1024 < props.maxSize;
  if (!maxSize) {
    message.error(`上传文件大小不能超过 ${props.maxSize}MB!`)
    return false
  }

}

const handleChange = (info) => {
  // emit('change', info)
}

const handleRemove = (file) => {
  previewImageUrl.value = ''
  emit('update:value', '')
  emit('remove', file)
}

const handlePreview = async (file) => {
  if (!file.url && !file.preview) {
    file.preview = await getBase64(file.originFileObj);
  }
  previewImage.value = file.url || file.preview;
  previewVisible.value = true;
  previewTitle.value = file.name || file.url.substring(file.url.lastIndexOf('/') + 1);
}

const handleCancel = () => {
  previewVisible.value = false;
  previewTitle.value = '';
}

const request = async (params) => {
  // console.log('自定义上传')
  const { onSuccess, onError, file, onProgress } = params
  const apiObj = props.apiObj

  // console.log(params)
  // const data = new FormData();
  // const reader = new FileReader();
  // reader.readAsDataURL(option.file); //转为base64格式
  // const urlData = URL.createObjectURL(params.file); //转为blob格式（二进制文件）
  // data.append(params.filename, params.file);



  // // 获取后缀名
  // const fileExtension = file.name.substring(file.name.lastIndexOf(".") + 1);
  // // console.log(fileExtension);
  // // 关于 key 要怎么处理自行解决，但如果为 undefined 或者 null 会使用上传后的 hash 作为 key.
  // const qiniuKey = file.uid + '.' + fileExtension
  // const tokenData = await $API.common.getQiniuToken.post()
  // // console.log('tokenData', tokenData)
  // const qiniuDomain = tokenData.data.domain
  // const qiniuToken = tokenData.data.uptoken
  //
  // const returnServer = {
  //   filepath: '', //
  //   name: file.name, // 原始文件名称
  //   mimetype: file.type, // 文件类型
  //   fileext: fileExtension, // 文件后缀
  //   filesize: file.size, // 文件大小
  //   filename: qiniuKey, // 上传后名称
  //   hash: ''
  // }
  //
  // try {
  // /**
  //  * fname    ===> string，文件原文件名
  //  * params   ===> object，用来放置自定义变量
  //  * mimeType ===> 用来限制上传文件类型，为 null 时表示不对文件类型限制；限制类型放到数组里： ["image/png", "image/jpeg", "image/gif"]
  //  * @type {{fname, mimeType: (*[]|null), params: {}}}
  //  */
  // const putExtra = {
  //       fname: params.name,
  //       params: {},
  //       mimeType: [] || null
  //     },
  //     config = {
  //       useCdnDomain: true,
  //       region: null
  //     }
  //
  //   var observable = qiniu.upload(file, qiniuKey, qiniuToken, putExtra, config)
  //   var observer = {
  //     next(res){
  //       // 更新进度条
  //       onProgress({ percent: res.total.percent }, file)
  //       // console.log('上传进度', res.total.percent)
  //     },
  //     error(err){
  //       message.error('上传失败')
  //       loading.value = false
  //       emit('error', err)
  //     },
  //     complete(res){
  //       const imageSrc = qiniuDomain + '/' + qiniuKey
  //
  //       Object.assign(returnServer, {
  //         filepath: imageSrc,
  //         hash: res.hash
  //       })
  //       apiObj.post(returnServer).then(res2 => {
  //
  //         loading.value = false
  //         message.success('上传成功')
  //
  //         onSuccess(res2);
  //         previewImageUrl.value = imageSrc
  //         emit('update:value', res2.data[props.field])
  //         emit('finish', res2.data)
  //         // console.log(res)
  //       }).catch(err => {
  //
  //       })
  //       // console.log(returnServer)
  //       // console.log("qiniu complete", res);
  //     }
  //   }
  //   var subscription = observable.subscribe(observer) // 上传开始
  //   loading.value = true
  //
  // } catch (err) {
  //   console.log("Error: ", err);
  //   // const error = new Error("Some error");
  //   // onError({ err });
  // }
}
</script>

<style lang="scss" scoped>
.template-wrapper {
  position: relative;
  width: 100%;
  height: 100%;
  .loading-icon {
    position: absolute;
    left: 45%;
    top: 48%;
    font-size: 16px;
    z-index: 9;
  }
}
</style>
